package cn.t.util.common;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.*;
import java.util.Enumeration;
import java.util.Optional;

public class SystemUtil {

    /**
     * 获取应用变量
     * @param key 查找的参数key
     * @return value
     */
    public static String getApplicationVar(String key) {
        return Optional.ofNullable(SystemUtil.getSysProperty(key)).orElseGet(() -> SystemUtil.getSysEnv(key));
    }

    /**
     * 获取应用环境变量
     * @param key key
     * @return value
     */
    public static String getSysEnv(String key) {
        return System.getenv(key);
    }

    /**
     * 获取系统属性
     * @param key key
     * @return value
     */
    public static String getSysProperty(String key) {
        return System.getProperty(key);
    }

    /**
     * 获取进程ID
     * @return 进程ID
     */
    public static int getPid() {
        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
        String name = runtime.getName(); // format: "pid@hostname"
        return Integer.parseInt(name.substring(0, name.indexOf('@')));
    }

    /**
     * 获取ipv4地址
     * @return ipv4
     */
    public static String getLocalIpV4(boolean isPrivate) {
        return getLocalIp(Inet4Address.class, isPrivate);
    }

    /**
     * 获取ipv6地址
     * @return ipv6
     */
    public static String getLocalIpV6(boolean isPrivate) {
        return getLocalIp(Inet6Address.class, isPrivate);
    }

    /**
     * 获取本地ip
     * @return 本地ip
     */
    private static String getLocalIp(Class<? extends InetAddress> clazz, boolean isPrivate) {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                // filters out 127.0.0.1 and inactive interfaces
                if(ni.isLoopback() || !ni.isUp()) {
                    continue;
                }
                Enumeration<InetAddress> enumIpAdd = ni.getInetAddresses();
                while (enumIpAdd.hasMoreElements()) {
                    InetAddress inetAddress = enumIpAdd.nextElement();
                    if (!inetAddress.isLinkLocalAddress()
                        && (isPrivate == inetAddress.isSiteLocalAddress())
                        && clazz.isAssignableFrom(inetAddress.getClass())
                    ) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
            return "";
        } catch (SocketException e) {
           throw new RuntimeException(e);
        }
    }

    public static byte[] convertHostToBytes(String host) {
        try {
            return InetAddress.getByName(host).getAddress();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        }
    }

    public static void showMtu() throws SocketException {
        Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
        while (en.hasMoreElements()) {
            NetworkInterface ni = en.nextElement();
            System.out.println(" Display Name = " + ni.getDisplayName());
            System.out.println(" MTU = " + ni.getMTU());
        }
    }
}
